package hotel.gateway;

import hotel.rmi.HotelService;
import hotel.rmi.to.Guest;
import hotel.rmi.to.Room;
import hotel.server.RoomException;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Collection;

public class Dispatcher {

	HotelService service;

	DataOutputStream os;

	DataInputStream is;

	static final public int ROOMS_REQUEST = 1;

	static final public int BOOK_REQUEST = 2;

	static final public int GUESTS_REQUEST = 3;

	public void rooms() throws IOException {
		Collection<Room> rooms;
		rooms = service.getAvailableRooms();
		os.writeInt(rooms.size());
		for (Room room : rooms) {
			os.writeInt(room.getId());
			os.writeInt(room.getFreeCount());
			os.writeInt(room.getPrice());
		}
	}

	static public String readString(DataInputStream dis, int size)
			throws IOException {
		byte[] str = new byte[size];
		dis.readFully(str);
		return new String(str);
	}

	public void book() throws IOException {
		int roomId, nameLength;
		String name;

		roomId = is.readInt();
		nameLength = is.readInt();
		name = readString(is, nameLength);

		try {
			service.book(roomId, name);
		} catch (RemoteException e) {
			Throwable cause = e.getCause();
			if (cause.getClass().equals(RoomException.class)) {
				String msg = cause.getMessage();
				os.writeInt(msg.length());
				os.writeBytes(msg);
				return;
			} else
				throw e;
		}
		os.writeInt(0);
	}

	public void guests() throws IOException {
		Collection<Guest> guests = service.getGuests();
		os.writeInt(guests.size());
		for (Guest guest : guests) {
			String name = guest.getName();
			os.writeInt(name.length());
			os.write(name.getBytes());
		}
	}

	void doHandleRequest()
			throws IOException {
		int type = is.readInt();
		if (type == ROOMS_REQUEST)
			rooms();
		else if (type == BOOK_REQUEST)
			book();
		else if (type == GUESTS_REQUEST)
			guests();
		else
			System.err.println("Unknown type of request");
	}

	public Dispatcher(HotelService service, DataOutputStream os, DataInputStream is) {
		super();
		this.service = service;
		this.is = is;
		this.os = os;
	}
}
